package bankcorba;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import org.omg.CORBA.ORB;
import org.omg.CORBA.ORBPackage.InvalidName;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.CosNaming.NamingContextPackage.CannotProceed;
import org.omg.CosNaming.NamingContextPackage.NotFound;


/**
 * Applications r�parties
 * TP 3
 * Gestion de comptes bancaires, CORBA
 * 
 * Client d'une agence de la banque
 * 
 * @author Toto
 * @version 1.0
 */
public class BankClient {

	/**
	 * M�thode utilitaire de saisie du nom d'un compte
	 * @param in Flux d'entr�e (clavier)
	 * @return String Nom du compte
	 * @throws IOException 
	 */
	public static String getName(BufferedReader in) 
			throws IOException {
		String name = null;
		System.out.print("Nom du compte : ");
		name = in.readLine();
		return name;
	}

	/**
	 * M�thode utilitaire de saisie d'un mot de passe
	 * @param in Flux d'entr�e (clavier)
	 * @return String Mot de passe du compte
	 * @throws IOException
	 */
	public static String getPassword(BufferedReader in)
			throws IOException {
		String password = null;
		System.out.print("Mot de passe : ");
		password = in.readLine();
		return password;
	}

	/**
	 * M�thode de r�cup�ration du code op�ration
	 * @param op Code op�ration (sous forme d'une String)
	 * @return int Code op�ration
	 * @throws NumberFormatException
	 */
	public static int getOperation(String op) throws NumberFormatException{
		int operation = -1;
		operation = Integer.parseInt(op);
		return operation;
	}

	/**
	 * M�thode de r�cup�ration du montant de l'op�ration
	 * @param in Flux d'entr�e (clavier)
	 * @return int Montant saisi
	 * @throws IOException, NumberFormatException
	 */
	public static float getAmount(BufferedReader in)
			throws IOException, NumberFormatException {
		float amount = -1f;
		System.out.print("Montant : ");
		amount = Float.parseFloat(in.readLine());
		return amount;
	}

	/**
	 * Affichage du menu.
	 */
	public static void displayMenu() {
		System.out.println("\n****** Menu ******");
		System.out.println("Choix operation :");
		System.out.println(BankUtil.OPEN+" - Ouverture");
		System.out.println(BankUtil.CLOSE+" - Fermeture");
		System.out.println(BankUtil.DEPOSIT+" - Depot");
		System.out.println(BankUtil.WITHDRAW+" - Retrait");
		System.out.println(BankUtil.BALANCE+" - Consultation solde");
		System.out.println("quit - Quitter");
		System.out.print("> ");
	}


	public static String nomErreur(BankException be) {
		String s = "";
		switch(be.codeerreur) {
		case BankUtil.EXISTANT :
			s += "Compte deja present";
			break;
		case BankUtil.NONEXISTANT :
			s += "Compte inexistant";
			break;
		case BankUtil.INVPASSWORD :
			s += "Mot de passe non valide";
			break;
		case BankUtil.NEGBALANCE :
			s += "Solde insuffisant";
			break;
		}
		return s;		
	}
	
	
	

	/**
	 * Programme principal (les arguments sont optionnels)
	 * @param args[0] Nom du serveur
	 * @param args[1] Port du serveur
	 */
	public static void main(String[] args) {
		BufferedReader userInput = null;
		String theLine = null;
		int operation = -1;
		String name = null;
		String password = null;
		float amount = -1f;
		float response = 0f;

		
		try {
			userInput = new BufferedReader(new InputStreamReader(System.in));


			//Initialisation de l'ORB
			ORB orb = ORB.init(args, null);

			//Recuperation de la reference de l'objet mandataire (proxy) du service de nommage 
			org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
			NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);

			//Recuperation de la reference du servant grace au service de nommage 
			name = "bank";
			Bank allAccounts = BankHelper.narrow(ncRef.resolve_str(name));



			while(true) { 
				displayMenu();

				theLine = userInput.readLine();

				if(theLine.equals("quit")) { 
					System.out.println("Au revoir."); 
					break;
				}

				try {
					operation = getOperation(theLine);
					name = getName(userInput);
					password = getPassword(userInput);

					if(operation == BankUtil.DEPOSIT || operation == BankUtil.WITHDRAW) {	
						amount = getAmount(userInput);
					}


					switch(operation) {
					case BankUtil.OPEN : 
						response = allAccounts.openAccount(name, password);
						break;
					case BankUtil.CLOSE :
						response = allAccounts.closeAccount(name, password);
						break;
					case BankUtil.DEPOSIT :
						response = allAccounts.deposit(name, password, amount);
						break;
					case BankUtil.WITHDRAW :
						response = allAccounts.withdraw(name, password, amount);
						break;
					case BankUtil.BALANCE :
						response = allAccounts.getBalance(name, password);
						break;
					}

					System.out.println(response);
				}
				catch (BankException be) {
					System.err.println("Erreur : "+nomErreur(be));
					continue;
				}
				catch(NumberFormatException nfe) {
					System.err.println("Erreur : mauvais code operation\n"+nfe.getMessage());
					continue;
				}

			}
		} 
		catch (InvalidName e) {
			System.err.println(e.getMessage());
			e.printStackTrace();
		} 
		catch (NotFound e) {
			System.err.println(e.getMessage());
			e.printStackTrace();
		} 
		catch (CannotProceed e) {
			System.err.println(e.getMessage());
			e.printStackTrace();
		} 
		catch (org.omg.CosNaming.NamingContextPackage.InvalidName e) {
			System.err.println(e.getMessage());
			e.printStackTrace();
		} 
		catch (IOException e) {
			System.err.println(e.getMessage());
			e.printStackTrace();
		}
	}

}
